package edu.bbte;

public class SolveCube {
	private Matrix3D [] pieces3D;;
	private Matrix3D [] solutions3D;
	private int nrPieces;
	private MatrixCube [] piecesCube;
	private MatrixCube solution;
	private int size;
	private boolean used[];
	int lepes=0;
	MatrixCube cube;
	
	public SolveCube(Matrix3D [] pieces3D, int nrPieces) {
		this.pieces3D = pieces3D;
		this.nrPieces = nrPieces;
		
		size = pieces3D[0].getSize();
		solutions3D = new Matrix3D[nrPieces];
		piecesCube = new MatrixCube[nrPieces];
		solution = new MatrixCube(size);
		used = new boolean[nrPieces];
		for (int i=0; i < nrPieces; ++i) {
			//pieces3D[i].printMatrix();
			piecesCube[i] = new MatrixCube(size);
			piecesCube[i].setCube(this.pieces3D[i]);
		}
		solutions3D[0] = new Matrix3D(size);
		solutions3D[0] = pieces3D[0];
		solution.setCube(solutions3D[0]);
		used[0] = true;
		cube = new MatrixCube(size);
	}
	
	public void solve(int i) {
		++lepes;
		
		out :
		for (byte l = 1; l < nrPieces; ++l) {
			boolean found = false;
			if (!used[l]) {
				used[l] = true;
					MatrixCube [] cubeListR = piecesCube[l].listOfCubeRotations();
					int j = 0, k = 0;
					while (j<24) {
						MatrixCube [] cubeListS = cubeListR[j].listOfCubeShifts(size-1, size-1, size-1, size-1, size-1, size-1);
						k = 0;
						while (k < cubeListS.length) {
							if (solution.canAddCubes(cubeListS[k])) {
								found = true;
								cube = cubeListS[k];
								System.out.println(lepes + " "+i+" "+(j)+" "+(k));
								if (61==lepes)
									System.out.println();
								solutions3D[l] = new Matrix3D(size);
								solutions3D[l] = cube.getCube();//.setMatrix(cubeListS[k].getCube().getMatrix());
								solution.sumCube(cube);
								//cube.printAll();
								//solution.printAll();
								solve(i+1);
								//solution.printAll();
								//System.out.println("Ki kell vonni");
								//cube.printAll();
								if (solution.differenceCube(cube)) {
									lepes=lepes-1;
									//System.out.println("Ki lehet vonni");
									//cube.printAll();
									//solution.printAll();
								}
								//solution.printAll();
							}
							++k;
						}
				//********************************************************************************
				//***************************************
				// kovetkezo elem a forgatasokbol
						++j;
					}
					if (found) {
					
					}
			
					if (isAllUsed()) {
						System.out.println("Megvan a megoldas!"+i+" "+nrPieces);
						solution.getCube().printMatrix();
						return;
					}
					used[l] = false;	
					if (!found)
						return;
				}
			}
		//--lepes;
	}
	
	public void addCube(MatrixCube cube, int l, int i) {
	//	System.out.println(lepes + " "+i+" "+(--j)+" "+(--k));
		if (61==lepes)
			System.out.println();
		solutions3D[l] = new Matrix3D(size);
		solutions3D[l] = cube.getCube();//.setMatrix(cubeListS[k].getCube().getMatrix());
		solution.sumCube(cube);
		//cube.printAll();
		//solution.printAll();
		solve(i+1);
		//solution.printAll();
		//System.out.println("Ki kell vonni");
		//cube.printAll();
		if (solution.differenceCube(cube))
			lepes=lepes;
			//System.out.println("Ki lehet vonni");
		//solution.printAll();

	}

	public boolean isAllUsed() {
		for (int i=0; i<nrPieces; ++i) 
			if (!used[i])
				return false;
		return true;
	}
	
	public Matrix3D[] getSolutions3D() {
		return solutions3D;
	}

}
